//package com.example.intercepter;
//
//
//import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
//import org.apache.ibatis.executor.CachingExecutor;
//import org.apache.ibatis.executor.Executor;
//import org.apache.ibatis.mapping.BoundSql;
//import org.apache.ibatis.mapping.MappedStatement;
//import org.apache.ibatis.mapping.ParameterMapping;
//import org.apache.ibatis.mapping.SqlCommandType;
//import org.apache.ibatis.plugin.*;
//import org.apache.ibatis.reflection.MetaObject;
//import org.apache.ibatis.reflection.SystemMetaObject;
//import org.apache.ibatis.session.Configuration;
//import org.apache.ibatis.session.ResultHandler;
//import org.apache.ibatis.session.RowBounds;
//import org.apache.ibatis.type.TypeHandlerRegistry;
//import org.springframework.stereotype.Component;
//
//import java.lang.reflect.Field;
//import java.lang.reflect.Method;
//import java.text.DateFormat;
//import java.util.*;
//
//
//@Component
//@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})})
//public class MybatisOrgInterceptor implements Interceptor {
//
//
//    @Override
//    public Object intercept(Invocation invocation) throws Throwable {
//        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
//        SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
//        Object parameter = invocation.getArgs()[1];
//       /* if (parameter == null) {
//            return invocation.proceed();
//        }*/
//        if (SqlCommandType.SELECT == sqlCommandType) {
//            final Object[] args = invocation.getArgs();
//            CachingExecutor statementHandler = PluginUtils.realTarget(invocation.getTarget());
//            MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
//            Configuration configuration = mappedStatement.getConfiguration();
//            //获取执行方法的位置
//            String namespace = mappedStatement.getId();
//            //获取mapper名称
//            String className = namespace.substring(0, namespace.lastIndexOf("."));
//            //获取方法名
//            String methedName = namespace.substring(namespace.lastIndexOf(".") + 1, namespace.length());
//            //获取当前mapper 的方法
//            Method[] ms = Class.forName(className).getMethods();
//            for (Method m : ms) {
//                if (m.getName().equals(methedName)) {
//                    //获取注解  来判断是不是要储存sql
//                    MyOrg annotation = m.getAnnotation(MyOrg.class);
//                    if (annotation != null) {
//                        //需要替换sql参数
//                        Object parameterObject = args[1];
//                        // 假设我们想要添加一个额外的参数
//                        Map<String, Object> parameters = (Map<String, Object>) parameterObject;
//                        parameters.put("additionalParam", "newValue");
//                        BoundSql boundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
//                        // 执行的SQL语句
//                        String originalSql = boundSql.getSql();
//                        // SQL语句的参数
//                       // Object parameterObject = boundSql.getParameterObject();
//                        if(parameterObject != null){
//                            originalSql = showSql(configuration, boundSql);
//                        }
//                        System.err.println("sql :"+originalSql);
//                    }
//                }
//            }
//        }
//        return invocation.proceed();
//    }
//
//    @Override
//    public Object plugin(Object target) {
//        return Plugin.wrap(target, this);
//    }
//
//    @Override
//    public void setProperties(Properties properties) {
//        // TODO Auto-generated method stub
//    }
//
//
//    private Field[] getAllFields(Object object) {
//        Class<?> clazz = object.getClass();
//        List<Field> fieldList = new ArrayList<>();
//        while (clazz != null) {
//            fieldList.addAll(new ArrayList<>(Arrays.asList(clazz.getDeclaredFields())));
//            clazz = clazz.getSuperclass();
//        }
//        Field[] fields = new Field[fieldList.size()];
//        fieldList.toArray(fields);
//        return fields;
//    }
//
//    /***
//     * sql 参数替换
//     * @param configuration
//     * @param boundSql
//     * @return
//     */
//    public static String showSql(Configuration configuration, BoundSql boundSql) {
//        //获取参数对象
//        Object parameterObject = boundSql.getParameterObject();
//        //获取当前的sql语句有绑定的所有parameterMapping属性
//        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//        //去除空格
//        String sql = boundSql.getSql().replaceAll("[\\s]+", " ");
//        if (parameterMappings.size() > 0 && parameterObject != null) {
//            TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
//            /* 如果参数满足：org.apache.ibatis.type.TypeHandlerRegistry#hasTypeHandler(java.lang.Class<?>)
//            org.apache.ibatis.type.TypeHandlerRegistry#TYPE_HANDLER_MAP
//            * 即是不是属于注册类型(TYPE_HANDLER_MAP...等/有没有相应的类型处理器)
//             * */
//            if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
//                sql = sql.replaceFirst("\\?", getParameterValue(parameterObject));
//            } else {
//                //装饰器，可直接操作属性值 ---》 以parameterObject创建装饰器
//                //MetaObject 是 Mybatis 反射工具类，通过 MetaObject 获取和设置对象的属性值
//                MetaObject metaObject = configuration.newMetaObject(parameterObject);
//                //循环 parameterMappings 所有属性
//                for (ParameterMapping parameterMapping : parameterMappings) {
//                    //获取property属性
//                    String propertyName = parameterMapping.getProperty();
//                    System.err.println("propertyName: "+propertyName);
//                    //是否声明了propertyName的属性和get方法
//                    if (metaObject.hasGetter(propertyName)) {
//                        Object obj = metaObject.getValue(propertyName);
//                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
//                    } else if (boundSql.hasAdditionalParameter(propertyName)) {
//                        //判断是不是sql的附加参数
//                        Object obj = boundSql.getAdditionalParameter(propertyName);
//                        sql = sql.replaceFirst("\\?", getParameterValue(obj));
//                    }
//                }
//            }
//        }
//        return sql;
//    }
//
//    /**
//     * 获取参数值
//     * @param obj
//     * @return
//     */
//    private static String getParameterValue(Object obj) {
//        String value = null;
//        if (obj instanceof String) {
//            value = "'" + obj.toString() + "'";
//        } else if (obj instanceof Date) {
//            DateFormat formatter = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, Locale.CHINA);
//            value = "to_date('" + formatter.format(obj) + "','yyyy-MM-dd hh24:mi:ss')";
//        } else {
//            if (obj != null) {
//                value = obj.toString();
//            } else {
//                value = "";
//            }
//
//        }
//        System.err.println("获取值: "+value);
//        return value;
//    }
//}
//
